﻿namespace Blaze.Framework
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;

    /// <summary>
    /// Blaze核心驱动对象。
    /// </summary>
    [Singleton]
    public class BlazeEngine : MonoBehaviour, IGameEngine
    {
        /// <summary>
        /// 当屏幕尺寸变更时触发此事件。
        /// </summary>
        public event Action ScreenSizeChanged;

        /// <summary>
        /// 获取<see cref="BlazeEngine"/>的唯一实例。
        /// </summary>
        public static BlazeEngine Instance { get; private set; }

        /// <summary>
        /// 获取一个值，表示游戏是否正在退出。
        /// </summary>
        public static bool IsShuttingDown { get; private set; }

        #region IGameEngine Members

        /// <summary>
        /// 注册每帧更新的对象。
        /// </summary>
        /// <param name="updatable">自我更新的对象</param>
        public void RegisterUpdatable(IUpdatable updatable)
        {
            mUpdatables.Add(updatable);
        }

        /// <summary>
        /// 取消注册每帧更新的对象。
        /// </summary>
        /// <param name="updatable">自我更新的对象</param>
        public void UnregisterUpdatable(IUpdatable updatable)
        {
            mUpdatables.Remove(updatable);
        }

        #endregion

        /// <summary>
        /// 初始化。
        /// </summary>
        [RuntimeInitializeOnLoadMethod]
        public static void Initialize()
        {
            if (mIsInitialized)
                return;
            mIsInitialized = true;
            Instance = Singleton.Get<BlazeEngine>();
        }

        protected void LateUpdate()
        {
            detectScreen();
        }

        protected void OnApplicationQuit()
        {
            IsShuttingDown = true;
        }

        protected void Update()
        {
            for (var i = 0; i < mUpdatables.Count; i++)
            {
                var updatable = mUpdatables[i];
                updatable.Update();
            }
        }

        private void Awake()
        {
            Instance = this;
            mLastScreenWidth = Screen.width;
            mLastScreenHeight = Screen.height;
        }

        private void detectScreen()
        {
            if (Screen.width == mLastScreenWidth
                && Screen.height == mLastScreenHeight)
                return;

            if (ScreenSizeChanged != null)
                ScreenSizeChanged();

            mLastScreenWidth = Screen.width;
            mLastScreenHeight = Screen.height;
        }

        private static bool mIsInitialized;
        private int mLastScreenHeight;
        private int mLastScreenWidth;
        private readonly List<IUpdatable> mUpdatables = new List<IUpdatable>();
    }
}